﻿namespace NetFx.AST
{
  using System;
  using System.Text;
  using System.Collections;
  using System.Collections.Generic;

  using NetFx.SMIL.Definitions;
  using NetFx.SMIL.References;

  /// <summary>
  /// 知识节点。
  /// </summary>
  /// <remarks>
  /// 知识节点是自然语言表述的基本结构。
  /// 一个知识节点由以下部分构成：
  ///   名称，属性（包括类型），链节点，子节点。在当前论域中，我们假定知识以语言表述。我们通过语言表达，传递，理解知识。
  /// 我们通过对语言描述中的各个组分之间关系的理解，体会事物之间的关系。
  /// 
  ///
  /// 例如，我们通过语素之间的并置来理解派生关系（也可能是同位关系）；通过语素之间的复杂并置来理解定义关系。
  /// 
  /// 所谓复杂并置，是指并置的两个语素中的一个或者两个都是复杂语素。例如，如果两个语素中，只有一个语素
  /// 是复杂语素，另一个是简单语素，这一般意味着对事物（或者行为）的定义，而如果两个语素都是复杂语素，那么
  /// 几乎可以肯定这个定义是对行为的定义。
  /// 
  /// 由于理论本身也在探索之中，所以完全可能存在大量的未能标定为词汇的语义， 例如语素在这里被关联为“语义元素”，
  /// 而这个关联可能和语言学中的“语素”并不相同。
  /// 
  /// 再例如描述，描述是指用某种语言对事物，行为，方法等进行的描写，是“可以写出来的”或者“可以说出来”的理解。
  /// 
  /// 例如语言，语言是指构成语言的所有知识基本符合某种约定为前提的描述约定。本质上不存在“某种”语言，
  /// 因为用“某种”语言描述的事物，并不保证所有的描述方法都符合一组完全定义的约定。或者说，对于任何一种
  /// 语言都没有绝对的，完全定义的约定。例如，我们可以对任意两个判断使用“而且”，而对于两个事物使用“而且”
  /// 则是未定义的。未定义并不意味着无效或者错误，而是意味着在一些情况下无效或者错误，而在另一些情况下是否
  /// 有效则未可得知。
  /// 
  /// 即便能够对所有的情况进行完全的考察，我们也无法保证能够对一种语言做出静态的，永远不变的语法约定（我们
  /// 已经强制定义的高级语言一类除外）。
  /// 
  /// 由于神经系统本身的特性，我们常用的一些词汇和结构会被从个别知识中得到抽象，称为“全局知识”，而这些
  /// 知识模式又会被应用于对未知领域的描述，我们实质上是从这个角度来定义一种自然语言的 － 在一种自然语言
  /// 中，人们倾向于使用某些从大量类似知识模式中抽象出来的知识模式（语法以及语言结构）对所有已知和未知的
  /// 知识进行描述，这种倾向使得我们意识到我们使用了某种特定的语言。
  /// 
  /// 在计算机上实现的自然语言理解也存在类似的问题。我们尝试创立的概念语言（自然语言形式的知识描述以及程序设计
  /// 语言）也存在类似的问题。
  /// 
  /// 不同在于，概念语言对于已有知识模式（显现为语法）并不越权使用。
  /// 我们一般会移用已有的知识模式来表述类似于已知被描述事物的新事物，而这这种易用在概念语言中并不适用。
  /// 由于概念语言要最终生成可执行代码，所以，它也存在类型检查的问题。概念语言要求必须保证被描述对象符合
  /// 描述类型（或者是要求类型的显示派生类型）。所以概念语言本身是类型严格的，这就避免了在程序设计上使用
  /// “诗歌”模式，进而避免了分类不确定性。
  /// 
  /// 
  /// 知识表现以及实现
  /// 
  /// 知识节点最终要被表达为程序集的元数据，即将知识生成代码。
  /// 
  /// 只有生成为代码的知识才能够在.NET平台上得到其他语言的直接应用；未能生成代码的知识，或者始终不将知识生成代码
  /// 的做法也是有效的，这种有效性体现在知识平台的构建上。
  /// 
  /// 当知识本身以树或者网络形式表示时，它可以是具有任意内容，任意语义，以及任意模式的。然而，若将知识表述转化
  /// 为代码表述，生成方法，类型以及程序集，则需要对知识的组织形式提出要求；另一个选择是对知识的组织进行识别。
  /// 
  /// 计算机高级语言使用前一种方式，而概念语言使用后一种方式。
  /// 
  /// 概念语言对知识的语言表述形式进行识别，标定关键部分，提取并重新组合知识表述以适应代码生成。
  /// 
  /// 怎样实现知识的语言表述形式识别？
  /// 
  /// 我们参照语言系统的内部关系模型进行识别。保证符合如下原则：
  /// 概念语言遵循如下基本原则：
  /// 
  ///     已知优先：  首先在已知范围内发现描述所表达的含义，包括描述是否符合已有的语法结构（语法识别），
  ///                 描述是否包括已有的事物类型（归类）等。
  /// 
  ///     未知补充：  所有在已知范围内未发现的描述所表达的含义，应对现有知识体系进行补充。这包括对类型
  ///                 的补充（类的定义），对类型的细化描述（字段的定义），对类型的讨论补充（方法的定义），
  ///                 和对类型的相关补充（描述符以及内部类等）。
  /// 
  ///     二元结合：  使用二元关系作为最基本的关联依据。
  /// 
  /// 
  /// 关于语法记录：
  /// 
  ///   语法将记录于元数据标记属性（Attribute）中。通过使用属性检索方法的语法（而不是签名）。
  ///   签名将根据语法自动生成，尤其对Method而言。
  /// 
  /// 如何建立语法库：
  /// 
  ///   需要建立语法库以适应语法和对应的方法之间的等价关系。
  ///   由于使用标记属性，任何程序集成员（Type，Field，Method）都可以被检索。
  ///   对给定程序集进行语法检索之后，即可建立程序集的语法库。
  /// 
  /// 
  /// 设计原则（Rationale）：
  /// 概念点不是神经节点。若作为对比，概念点更像是神经链接上积累的物质而构成的
  /// 关系。这也就是概念的实际情况。
  /// 
  /// 所以，概念节点不是为了便于神经节点的学习而设计的。若需要建立对等的神经
  /// 网络，则需要一些必要的转化（或者称为再次学习）。
  /// 
  /// 同样由于概念点不是为了神经节点的学习而设计，概念点只具有有限的知识架构能力。
  /// 这种能力虽然可以处理多数的无语法语言所表达的知识结构，但无法进行有效的推理。
  /// 由概念节点构成的概念网络是一个静态网络。除非为概念节点引入基于实并行的神经
  /// 节点。
  /// 
  /// 难点：如何区分事物和过程。
  /// 
  /// 在计算机中，必须要表述的就是事物（表现为数据）和过程（表现为程序）。
  /// 事物的进一步抽象得到了对象和类的概念。
  /// 过程的进一步抽象得到了方法的概念。
  /// 对象和方法显然也是面向对象的基本概念。
  /// 
  /// 引入无语法语言之后，一切都需要使用模式（Pattern）而不是关键字来限定。
  /// 那么，一个用于区分事物和过程的模式就是必须的。
  /// 
  /// 在现有的模式中，内置显然更易用于表达事物的组成关系；并置则易于表达
  /// 有序的状态变化。可是，并置也被用于表达语法序列和关系的传递。
  /// 
  /// 需要一个新的模式来把过程从事物中区分出来（而不引入任何动词标记）。
  /// 
  /// 我们知道，并置易于表达顺序，而内置则可以划分空间。
  /// 
  /// 一个过程的存在，是以其连续的事件（或者步骤）相继出现（或者进行）而得到
  /// 表达的；先前的事件总是可以影响其后的事件，而反之则不然。
  /// 
  /// 从连续性上考虑，我们可以使用类似如下的模式：
  /// [*][*][*][*]...
  /// （每个星号代表一个事件或者步骤）。
  /// 这是一个连续并置模式，和一般的语法并置没有区别。
  /// 
  /// 从因果性上考虑，我们可以使用另一个模式：
  /// 
  /// [*[*[*[*[*]]]]]
  /// 
  /// 这又是一个标准的递归内置，和一般的事物表达没有区别。
  /// 
  /// 但是，既然节点既支持内置，又支持并置，为什么不将
  /// 内置和并置组合起来，形成一种混合方式？
  /// 
  /// 也就是说，节点p的内置节点p'同时也是p的并置节点。
  /// 
  /// 这种节点，称为双置节点。
  /// 
  /// 立即的并置节点只有一个，但内置节点可以很多。过程应
  /// 按照并置的顺序进行；同时，内置的影响也将被传递下去。
  /// 
  /// 后置节点的实现得到修正：每个节点若可以具有
  /// 多个直接后置节点，除非这个节点具有多个输出。
  /// 
  /// 方括号语法生成新的节点，并只记录这个节点为后置节点。
  /// 由此，方括号语法并不支持多个直接后继节点，由于可以
  /// 存在多个立即后置节点，每个节点也不再具有确定的立即
  /// 前置节点，所以，反向引用将无法进行（已经增加Former
  /// 属性记录向前引用）。
  /// 
  /// 双置节点：
  /// 
  /// 可以使用方括号语法将带有特殊标记的节点定义为双置
  /// 节点。即既是内置节点，又是后置节点。
  /// 
  /// 需要指出，此方法将内置节点直接复制到直接后置节点
  /// 列表，这使得这些内置节点实际上是“并行节点”。
  /// 
  /// 所谓并行节点，是指在这些节点都是当前节点的直接后置
  /// 节点，而这将导致这些节点在逻辑上并行。
  /// 
  /// 所以，不要使用这种方法直接定义函数（或者方法），
  /// 而应当保持双置节点的特性，必要的时候，可以用自动
  /// 转化来保持（比如某种自动转化的语法）。
  /// 
  /// 实现：在添加内置节点的时候，
  /// 具有FormerParent属性声明的内置节点的Former
  /// 属性可以被直接设定为当前节点。
  /// 
  /// 
  /// 所有的方括号语法都将定义推入下一个节点，即新产生的
  /// 节点，所以，不要使用方括号语法定义当前节点。
  /// 
  /// 使用Header属性可以获得最先定义的节点，对于最顶层来说。
  /// 例如使用：     
  /// ConceptPoint t = ConceptPoint.of("ABC")["DEF"]["GHI"]["JKL"].Header;
  /// 就可获得最先定义的具有ABC属性的节点（以及用Relative链接的整个序列）。
  /// 注意，第一个括号是圆括号，最后一个属性是Header。
  /// 
  /// 使用副词Afterwards表达将FormerParent置入属性。
  /// 以下示例给出并行性的解释：
  /// 
  ///      ConceptPoint threads = ConceptPoint.of("Threads")
  ///      [
  ///        ConceptPoint.of("ThreadA").Afterwards
  ///        [
  ///          ConceptPoint.of("ThreadA_V"),
  ///          ConceptPoint.of("ThreadA_1").Afterwards
  ///          [
  ///            ConceptPoint.of("ThreadA_2").Afterwards
  ///          ]
  ///        ],
  ///        ConceptPoint.of("ThreadB").Afterwards
  ///      ].Header;
  /// 
  /// 其中，Thread_A和Thread_B可以视作两个并行的线程。
  /// 而ThreadA_1,ThreadA_2,ThreadA_3才是Thread_A的真正过程
  /// （这和普通的函数写法差别很大）；由于ThreadA_V没有
  /// Afterwards副词，所以，ThreadA_V可以被视作和ThreadA_2
  /// 处于同一空间的事物，且这一事物只在这个空间存在（
  /// 考虑限定作用域的局部变量）。
  /// 
  /// 显然，ThreadA_V没有FormerParent属性，它的Former属性
  /// 也就不会设定到它的Parent（ThreadA）上。
  /// 
  /// 这指示了它不会具有任何过程性，只能是一个事物。
  /// 相对而言，处在后置位置上的不具有过程性的节点却具有Former
  /// 属性，可以通过追踪到Header的方式来判断整个后置序列是否＝
  /// 是一个事物还是一个过程（IsProcedure）。
  /// 
  /// 为了便于使用，定义操作符＋以方便内置。
  ///  ConceptPoint threads = ConceptPoint.of("Threads")
  ///    [
  ///      ConceptPoint.of("ThreadA").Afterwards
  ///        + ConceptPoint.of("ThreadA_V")
  ///        + ConceptPoint.of("ThreadA_1").Afterwards
  ///        + ConceptPoint.of("ThreadA_2").Afterwards,
  ///      ConceptPoint.of("ThreadB").Afterwards
  ///    ].Header;
  /// 
  /// 注意，ThreadA_V同样没有Afterwards副词，本示例和上个示例
  /// 的语义完全一致。
  /// 
  /// 评论：
  /// 
  /// 使用Afterwards或者FomerParentLitteral的确引入了特殊的成分，
  /// 但是这些特殊成分并不超越Pattern的范围。无论以何种方式表达，
  /// 双置的表达都是很难实现的。这必须引入某种自动化支持，也就是
  /// 属性，或者说某些先定的条件 － 而且是用户无法输入的。
  /// 
  /// 事实上，还有一种方法可以帮助解决这个问题：在属性中，引入
  /// Parent的名字。但是问题在于，对于过程而言，Parent往往没有名字，
  /// 而且方括号语法也很难支持将属性和节点同时定义在一个方括号里面
  /// 的要求。
  /// 
  /// 现在，我们已经可以确定的表明一个过程的最外层结构了。
  /// 这个过程节点是纯过程，没有任何修饰成分，若要修饰
  /// 这个过程，需要使用前置（并置）。为什么不能使用后置
  /// 并置？这是因为后置是在内部的并置。
  /// 
  /// 然而，无法将前置并置和过程的Header区分开，必须再想办法。
  /// 
  /// 可以想到，虽然纯过程要求其前置节点不可以为它的父节点。
  /// 但是它的父节点实际上已经参入过程之中，并成为了纯过程
  /// 的论域。
  /// 
  /// 所以，真正的过程的开始，是在父节点，而不是纯过程节点本身。
  /// 
  /// 函数类：
  /// 
  /// 
  /// 虽然父节点还可能包含事物节点和其他过程节点，但当前过程
  /// 节点的存在已经决定了父节点存在的意义：提供论域。
  /// 
  /// 所以，若将此父节点类比为“类”，那么它将是实现“过程”接口
  /// 的无名类。其中的“字段”包括影响过程的字段和被过程影响的
  /// 字段以及一些过程内部的字段。
  /// 
  /// 我们的确可以定义这个类，但是我们也以将它改写成一个普通的函数。
  /// 
  /// 请参阅Demonstration.cs 中 Function 的定义。
  /// 
  /// 在Function中，并没有直接定义任何“函数”或者“方法”。
  /// 因为Function就是“函数”或者“方法”。
  /// 
  /// 控制流是通过对 ReturnValue 的获取而传递的。
  /// 
  /// 从面向对象到面向事实的进化是自然的。准确的说，计算机语言将
  /// 不断的向自然语言靠近，不是更进一步的抽象，而是更多的具体化。
  /// 
  /// Demonstration2.cs中给出了函数的面向事实版本。
  /// 
  /// 函数的概念被替换为“过程”(Process)，参数被替换为“参与者”(Participators),
  /// 返回值被替换为最终结果(FinalResult)。
  /// 
  /// 调用GetStringLength相当于引发了一个事件。
  /// 
  /// GetStringLength g = GetStringLength.it();
  /// 
  ///      g["text"].Instance = "ABCD";
  /// 
  /// Console.WriteLine w = Console.WriteLine.it();
  /// 
  ///      w["ouput"] = g.FinalResult;
  /// 
  /// 本质上来说，任何参与者的到来都可能引发事件的发生，而且事件的发生也不一定总是伴随着
  /// 一个结果（也就是说，不能依赖得到结果这个事件的发生）。
  /// 
  /// 我们引入关键参与者的概念，假定一个或者多个关键参与者的到来将导致事件的发生。
  /// 
  /// 这时候，即便不引发w.FinalResult, 由于output是关键参与者，w也可以实现输出。
  /// 
  /// 关键参与者的概念可能不易于理解，但是作为语言来说，如果动宾短语没有得到宾语，那么这个短语
  /// 就不完整。同样的，关键参与者起着宾语的作用。而其他参与者只起到补语的作用。
  /// 
  /// 老实的说，这种用法实在是很痛苦！
  /// 
  /// 所以，用这种方式虽然可以表达函数，但是比起用动宾短语表达，还很不好用（作为内部表达可能还有一
  /// 些意义）。
  /// 
  /// 回到Threads过程：
  /// 
  /// 即便Thread过程不是由两个独立的Thread并行构成，
  /// 一个Thread过程也的确可以描述一个“过程论域”。
  /// 
  /// 由此，这个过程论域就可以和其他的节点进行并置，
  /// 交换信息。
  /// 
  /// 对过程论域进行并置，相当于为“函数体”（Body）增加“函数头”（Signature）。
  /// 
  /// 可以想到，在过程内部，完全可能出现过程的定义。
  /// 
  /// 若定义具有并置，即出现函数头，则可以当作一般函数使用；若没有并置，
  /// 则可以当作匿名函数使用（然而可能永远无法调用）。
  /// 
  /// 所以一定要对函数体进行并置。若不进行并置，过程可能创建相应的线程。
  /// 
  /// 然而创建的线程却不会执行，这是因为这个线程不可能得到控制流，这显然是一种浪费。
  /// 
  /// 若要过程得到控制流，则过程必须被引用。
  /// 
  /// 引用不可能发生在未被并置的函数体上。这是因为这样的函数体无法通过名称或者签名
  /// 找到；而且这个函数体的外部都是事物定义，控制流也不可能流过事物定义达到函数体。
  /// 
  /// 所以，通过自顶向下的分析，找到最上层的“函数体”，通过并置就可以定义函数了！
  /// 
  /// 至于函数内部有什么？可能有函数，变量或者是类，这要看如何定义变量和类了。
  /// 
  /// 
  /// 关于函数（过程）的最重要的问题就是它的语法。
  /// 
  /// 语法显然是要通过和函数体（也就是过程论域）的并置而体现。
  /// 
  /// 然而问题在于如何表达这个语法：
  ///   哪些词是固定的，那些词是角色（Role），有多少种不同的表达等等。
  /// 
  ///   不同的表达方式可以通过内置实现。
  /// 
  ///   由于没有Afterwards，不同的表达不构成过程。
  ///   
  ///   由于要通过并置，使得函数体得到角色（也就是参数）的名称，
  ///   所有的角色名称必须出现在最顶层。
  ///  
  ///   事实上，在这个区间，我们甚至可以定义类和方法。但问题同样在于引用的困难
  ///   通过并置得到函数头（Signature）的函数体是没有名称的。函数头也不可能将
  ///   其名称字段直接传递到父节点。所以在这个范围里面进行的各种有名称的定义
  ///   都将只是局部的，不可能被外部引用的。
  /// 
  ///   所以，有必要查看各个节点的可见性！
  /// 
  /// 例如：
  /// 
  /// [
  ///   [打开] [文件 (角色)],
  ///   [文件 (角色)] [.] [打开]
  /// ]/* 并置 */
  /// [
  ///   函数体
  /// 
  /// ]＃获得函数头
  /// 
  /// 那么，如何标定一个节点是否为角色（具有角色属性）呢？需要遍历它存在的空间中的所有引用，
  /// 如果被引用到，即为角色。否则既是确定的单词。
  /// 
  /// 幸好事实不是这样简单！解析过程不允许“确定单词”的存在。或者说，如果出现了“确定单词”，
  /// 就必然意味着这个单词没有得到解析。
  /// 
  /// 如何处理这些没有得到解析的单词呢？
  /// 
  /// 
  /// 首先，这些单词将被提升，到达父层。这是因为在当前层未能得到解析，而且当前层是一个“过程”层。
  /// 
  /// 我们知道，一个过程如果没有标识则无法被引用。这迫使未得到解析的单词成为“过程”的标识。
  /// 
  /// 或者说，这些单词首先和当前的过程层相联系，然后又被作为代表向父层提交。
  /// 
  /// 在父层，通常是一个事物描述层，单词是被对应的过程描述并置的。
  /// 
  /// 这时候，这些单词进入了可以作用的论域：事物描述层。一旦这个论域被并置到其他地方，这些单词
  /// 的论域也被相应的扩展，例如：
  /// 
  /// public class File
  /// {
  ///   [Open][File][...]
  /// }
  /// File file;  //并置
  /// Open file   //扩展的应用。
  /// 
  /// 论域扩大的问题同样在这里存在。
  /// 
  /// 通过并置，file得到了File的全部论域。但是在file之外，却没有File的论域。这个问题可以通过一个“紧凑的论域”来解决。
  /// 
  /// 也就是说，假定在file之外很小的一个空间“*file*”上存在file的论域，那么就可以应用Open了。 ＃小论域
  /// 
  /// 还有一个问题，就是所谓角色的类型。如何确定角色File是否是File类型呢？是否可以单凭文字来识别呢？如果出现两个File改怎么办？
  /// 
  /// 所以，在[File]需要一个File并置：  [[File][file]]
  /// 
  /// 这很麻烦～ 虽然file被内部引用，而Open没有被引用，但这并不保证file的类型得到了证实。可是，话说回来，如果file的类型无法在
  /// 内部引用中得到证实，那么file是如何被引用的，也就成了问题。
  /// 
  /// ＃自动识别
  /// 
  /// 简单的说，总有一些标志使得file可以得到它的类型。如果不能确切的知道file是何种类型，那么就可以认为在理解上出现了
  /// 失败 － 对于人来说也是一样的。虽然可以通过判断字符串来了解file的类型，但这将只是最后一步。包括汉语在内的许多语言并
  /// 没有大小写的概念，相同的词也不一定就具有相同的意思。如果经过分析，“文件”这个词被引用，但不确定它是什么类型，那么
  /// 只能假设“文件”这个词所说的就是当前的事物“文件”。显然，需要对File，file，myFile，FileA等等进行分析，若分析不到
  /// 需要的内容，则只能进入“无法识别”状态。
  /// 
  /// 使用File并置不仅麻烦，还引入了一个层次。file必须冲出一个额外的层次才能够被引用。
  /// 
  /// 除非：对于无名的事物描述，存在一种自动命名的机制，使得它可以获得来自于内部的名字。＃无名命名
  /// 如果可以实现，无名描述中必须有且只有一个描述。
  /// 
  /// 同样的，无名命名也可以应用到函数并置。使得函数具有内部为定义单词的名字
  /// （也只要每个内置的第一个未定义单词）。
  /// 
  /// 可以想到， 
  /// 
  /// Open File A
  /// 
  /// 实际上使用了File A 并置和A的小论域。
  /// 
  /// 由于使用方括号语法，上述表达应为： [Open][[File][A]] 并置是明显的，而且Open也只作用于过程之中（在过程中的解析和在事物
  /// 描述中的解析方式不同）。
  /// 
  /// 从字符串到方括号，分析程序需要实现的主要功能，就是给字符串加括号，以便于后来的分析和理解。
  /// 
  /// 在特定的论域中，即便仅使用Open A，A的类型也可以得到推测：若机器无法成功推测，则人也不能，在人和机器具有相同的知识的
  /// 前提下。
  /// 
  /// 还有一个问题，[File][A]并置，如何决定A是否是一个对象？
  /// 
  /// 这就要看A被使用的语境，通过上下文可以得到A是否是一个对象。
  /// 
  /// 例如 Open File file
  /// 是用来并置函数体的。
  /// 
  /// file在函数中被应用，也就是加入了特定的过程之中。但是File并未加入任何特定过程之中，至少不是它本身。
  /// 
  /// 这就可以区分File是实例还是类了。
  /// 
  /// 显然，单独写出 File file 并置。
  /// 是不能确定file是否是类的。
  /// 
  /// 但若已经知道file是实例，则file fileA 中的fileA 将必然只是实例 file 的别名。
  /// 
  /// 事实上，通过加入无意义的运算符来描述这个运算，可以使用“是”：
  /// 
  /// fileA 是 file.
  /// 
  /// File file 也可以用这样的方式： file 是File。
  /// 
  /// 无论如何，若不在过程中引用file，则file是类（它可以有很大的扩展）。
  /// 
  /// 若在过程中引用file，则file是实例。
  /// 
  /// 仅写出File file，file是类。无论是否使用“是”都是这样。
  /// 
  /// 像“是”一类的“虚词”（不是动词或者名词），本质上抽象于并置关系，这种关系必然对应了特定的信号。
  /// 人们通过对这种信号的识别和转化，将这种并置关系“说”出来，成为语言。
  /// 
  /// 可以想象，若对方没有这种并置关系的识别能力，“是”将是彻底没有意义的。
  /// 
  /// 无语法语言将被自动的映射到IL的某种抽象（例如SMIL）上，中间不应当存在任何的代码进行解释。
  /// 
  /// 某些数的写法问题等等可能由后端来识别，但是这些情况都是少数。
  /// 
  /// 
  /// Int32 A 这种情况，可能需要中间层和后端的通信来决定语义，但也不是很大的问题。
  /// 
  /// 
  /// ＃自我描述
  /// 
  /// 
  /// 无语法语言必须可以自我描述。
  /// 
  /// 所谓自我描述是指：无语法语言不仅能够以无语法形式存在，还必须可以从
  /// 中派生出任何形式的有语法语言来。
  /// 
  /// 比如，必须可以使用无语法语言来定义foreach。
  /// 而语法的转换过程仅由中间层实现。
  /// 
  /// 如何定义namespace？
  /// 
  /// [namespace][NAME]
  /// [{]
  /// 
  /// [}]
  /// 
  /// 这时，可能出现大量的未命名项目。
  /// 
  /// 我们可以考虑使用模板：什么是模板？
  /// 
  /// 模板是使得中间层可以学习语言使用方法的素材。
  /// 
  /// 比如上面的Name未被使用。为了让namespace得到定义，
  /// 上面的Name就必须被正确的使用一次。
  /// 
  /// 解析namespace的时候，显然不再过程之中。
  /// 所以namespace的模板不可能被引用，而只能被丢弃。
  /// 
  /// 这使得namespace的结构得到了体现。
  /// 
  /// 
  /// 
  /// 
  /// 如何定义foreach？
  /// 
  /// [foreach][(][Type][o][in][collection][)]
  /// [{]
  ///   
  /// [}]
  /// 
  /// 若不使用模板，也可以使用BNF形式来定义语法，
  /// 有的时候，需要对语法进一步的说明时，则采用
  /// 并置引入说明。
  /// 
  /// 还可以通过并置向中间层添加模式：
  /// 例如：
  /// 
  /// ["is"][""] //并置一个无意义的词。
  /// 
  /// [
  ///   [file][is][File]
  /// ]
  /// [
  ///   [file][File]
  /// ]
  /// 这种并置使得is具有了一定的意义。
  /// 再比如
  /// [
  ///   [File][file]
  /// ]
  /// [
  ///   [file][is][File]
  /// ]
  /// 表达了不同的含义。
  /// 
  /// # 如何将有语法语言和无语法语言进行互换？
  /// 
  /// 有语法语言的语法存在“可选”、“重复”
  /// 等概念。而无语法语言则没有这些概念。
  /// 
  /// 无语法语言可以标定类型，却不能识别类型是否匹配。
  /// 
  /// 相比较而言，无语法语言更为基本，支持的功能较少。
  /// 
  /// 
  /// 由于有语法语言是语义关系的体现，所以有语法语言
  /// 本身也会体现语义关系。
  /// 
  /// 比如 [file][is][File] （file为实例，File为类）
  /// 就表达了类属关系。
  /// 
  /// [File][file]表达实例化或者派生关系。
  /// 
  /// 总可以从并置抽象出关系，尽管不是所有的关系都有名字。
  /// 
  /// 有语法语言使用文字符号表达这些关系，使得这些关系也可以得到传递。
  /// 
  /// 从有语法语言到无语法语言的转化，基本上就是将有语法语言中以文字
  /// 体现的关系，映射到无语法语言中不用文字体现的关系上去。
  /// 
  /// 由于不用文字，在无语法语言中体现关系是很困难的。
  /// 
  /// 但是也不是不可能：比如语句结尾的“；”就可以表达双置关系。
  /// 
  /// 这使得我们开始考虑使用属性来记录关系 － 双置关系就是这样记录的。
  /// 
  /// 再考虑并置关系的映射
  /// 
  /// class A <=> [object][A]
  /// 
  /// class A:B <=> [B][A]
  /// 
  /// 需要使用关系映射来实现有语法和无语法之间的转换。
  /// 
  /// 可以使用并置实现模式的映射。
  /// 
  /// 
  /// 基本映射
  /// 
  /// [[A * (重复)]][[A][A][A]...]
  /// 
  /// [[A , (可选)]][[A],[]]
  /// 
  /// [[A *,(可选重复)]][[A][A][A]...,[]]
  /// 
  /// 如何分析得到重复模式？
  /// 
  /// [[A *]][[A]]
  /// [[A *]][[A][A]]
  /// [[A *]][[A][A][A]]
  /// 
  /// 假定在某一时段中，重复出现的模式会被识别。
  /// 
  /// 新的理解：
  /// 
  /// 无语法语言的实例可对应于人类记忆中的一个片断。
  /// 
  /// 我们在记忆中以虚拟网络的形式组织认知的事物。
  /// 
  /// 所谓虚拟网络，即不是神经网络本身。
  /// 
  /// 知识在记忆中的存在是分布式的。而一旦使用，
  /// 知识又可以构成一定程度上的结构（网络）。
  /// 
  /// 这足以证明虚拟网络的存在。
  /// 
  /// 事实上，知识在记忆中构造虚拟网络的方式，
  /// 类似于“引用”：某个节点A到另一个节点B的
  /// 链接并不使用神经本身，而是使用A的一个属性
  /// 和B的对应属性具有相同的值（或者二者具有
  /// 相同的属性）。
  /// 
  /// 所谓属性（不是节点属性），即相关于A的某个编码。
  /// 这个编码是内部的，通过某种协调方式而得到的，
  /// 并在A达到某种条件的时候可以激发出来。
  /// 
  /// 具体的神经实现可能是这样的：承载A的神经原
  /// 和一系列首尾相接的神经元相连。A达到某个条件
  /// 而释放一个脉冲，这个脉冲引发了首尾相接的
  /// 神经元组的连续反应，从而发出一系列信号。
  /// 这些首尾相继的神经元构成了A信号的“发射器”。
  /// 
  /// 这一系列信号的特性可能和首尾相接神经元组中
  /// 的每个神经元的物理特性有关。信号脉冲之间的
  /// 长短间隔，以及整个脉冲的长度，就可以视作
  /// 编码使用。
  /// 
  /// A释放的脉冲，引发了一个编码信号。这个编码信号
  /// 将通过主要输出通路达到主回路（主回路也是多路并行的）
  /// ，然后从主回路分发到各级主要输入通路。
  /// 
  /// 当某个（或者某些）通路上存在这一编码信号的
  /// “接收器”，并且这些接收器能够正确的识别
  /// 这一信号的时候，相应的识别别过程开启。
  /// 
  /// 所谓接收器，也是一系列首尾相继的神经元。
  /// 仅当这些首尾相继的神经元全部开启的时候，
  /// 接收器的末端才向它链接的主神经元发送信号。
  /// 
  /// 若这个主神经元就是B，那么它将被信号激活，
  /// 并释放其他信号。其实，接收器也就是发送器。
  /// 
  /// 从主神经元链接到首尾相继的神经元组，而这个
  /// 首尾相继的神经元组又回链接回到这个主神经元。
  /// 
  /// 激发是双向的，所以接收器也是发送器。
  /// 
  /// B被激活后，将开启所有和它相连的发送器。将引用
  /// 信号继续传递下去。
  /// 
  /// 可以看到，接收器或者发送器（或者叫做收发器）
  /// 体现了主神经元内承载的某种信息和其他主神经元内部
  /// 承载的信息之间互相引发的性质。
  /// 
  /// 按照上面的例子，A的激发可能引发一系列的回应，
  /// 这些回应又可能引发更多的回应。由此，关于A的一系列
  /// 记忆将浮现出来。
  /// 
  /// 概念节点并不是按照主神经元的功能而设计的。
  /// 
  /// 实际上，概念节点是按照常规神经元的功能来设计的。
  /// 
  /// 这并不意味着概念节点等价于一个常规神经元。但是
  /// 概念节点的设计应满足：它可以比较容易的转化为
  /// 神经元训练所需要的信息结构。
  /// 
  /// 
  /// 和节点最接近的是神经轴突。节点的直接后继列表
  /// 的概念就来自于轴突输出的目的细胞的概念。
  /// 
  /// 节点的细节（Details）概念对应于主细胞的相关细胞。
  /// 这时，节点被上推到主细胞的层次。
  /// 
  /// 在物理上尚且难以区分轴突和细胞本身，在这里也是一样的。
  /// 
  /// 细节可以被放在节点中，也主要是因为节点和细节的关系和
  /// 轴突和树突的关系类似。
  /// 
  /// 没有确切对应的就是节点属性。
  /// 
  /// 节点属性本质上并不真的存在。我们使用节点属性跟踪节点，
  /// 标定信号。这就像是在细胞上染色，让我们看清楚细胞的内部
  /// 结构。
  /// 
  /// 最终，节点包含的信息可能被用于其他目的，例如代码生成
  /// （这是主要的目的）。这就要求对节点进行标注。比如某个节点
  /// 可能表达“类”，另一个节点可能表达“方法”。
  /// 
  /// 只有依赖这种标注，不具有神经结构的系统才能够正确的使用
  /// 这些信息。同时，这些标注也为观察系统的演化提供了方便。
  /// 
  /// 
  /// 此外，有了属性标注，一些需要在长时间训练中才能够得到了
  /// 神经细胞的行为，可以用简单便捷的方式直接刻画。
  /// 
  /// 这使得由概念节点表达的信息，可以直接刻画成为对应的神经
  /// 网络。关于这一点，需要更细致的讨论。
  /// 
  /// 
  /// 
  /// 
  /// 
  /// 
  /// </remarks>
  public class ConceptPoint
  {
    #region Consts
    /// <summary>
    /// SignatureKeyLiteral
    /// </summary>
    /// <remarks>
    /// 内置属性应命名为用户无法通过键盘输入的名字。
    /// 这些名字仅能够在程序内部使用。
    /// </remarks>
    public const string SignatureKeyLiteral = "\uFFFF:SK";
    /// <summary>
    /// FormerParentLiteral
    /// </summary>
    public const string FormerParentLiteral = "\uFFFF:FP";
    /// <summary>
    /// AnyLiteral
    /// </summary>
    public const string AnyLiteral  = "\uFFFF:Any";
    /// <summary>
    /// NullLiteral
    /// </summary>
    public const string NullLiteral = "\uFFFF:Null";
    #endregion
    #region Statics
    #region Definitions
    /// <summary>
    /// 定义空节点。
    /// </summary>
    /// <remarks>
    /// 空节点具有NullLiteral名称
    /// 的属性。
    /// </remarks>
    public static readonly ConceptPoint Null  = ConceptPoint.of(NullLiteral);
    /// <summary>
    /// 定义任意节点。
    /// </summary>
    /// <remarks>
    /// 任意节点具有AnyLiteral名称
    /// 的属性。
    /// </remarks>
    public static readonly ConceptPoint Any = ConceptPoint.of(AnyLiteral);
    #endregion
    #region Operators
    public static ConceptPoint operator + (ConceptPoint former,ConceptPoint latter)
    {
      if (former != null && latter != null)
      {
        former.AddDetails(latter);

        //保证不打开任何新的后继序列。
        return latter.HasFormer ? latter : former;
      }
      //第一个非空节点将进入下一次添加。
      return latter;
    }
    #endregion
    #region Shortcuts
    public static ConceptPoint it()
    {
      return new ConceptPoint();
    }
    public static ConceptPoint of(ConceptPoint former)
    {
      return new ConceptPoint(former);
    }
    public static ConceptPoint of(params string[] attributes)
    {
      return new ConceptPoint(attributes);
    }
    public static ConceptPoint of(params ConceptPoint[] points)
    {
      return new ConceptPoint(points);
    }
    public static ConceptPoint of(ConceptPoint former, params string[] attributes)
    {
      return new ConceptPoint(former, attributes);
    }
    public static ConceptPoint of(ConceptPoint former, params ConceptPoint[] points)
    {
      return new ConceptPoint(former, points);
    }
    #endregion
    #endregion
    #region Fields
    protected ConceptPoint former                     = null;
    protected Dictionary<string, string> attributes   = null;
    protected List<ConceptPoint> details              = null;
    protected List<ConceptPoint> relatives            = null;
    #endregion
    #region Properties
    public virtual ConceptPoint Former
    {
      get
      {
        return this.former;
      }
      set
      {
        this.former = value;
      }
    }
    /// <summary>
    /// 获取真实的Header。
    /// </summary>
    /// <remarks>
    /// 由于可能出现Header为Parent的情况，
    /// 递归过程一旦发现Header为Parent则返回
    /// 当前节点。
    /// 这可以保证Header不会跨越层次。
    /// </remarks>
    public virtual ConceptPoint Header
    {
      get
      {
        if (this.HasFormer)
        {
          if (this.Former.HasRelative(this))
          {
            //If the former contains this as a relative,
            //this is the horizental header
            return this;
          }
          else
          {
            return this.Former.Header;
          }
        }
        return this;
      }
    }
    /// <summary>
    /// 获取当前节点的第一个细节。
    /// </summary>
    public virtual ConceptPoint FirstDetail
    {
      get
      {
        return this.HasDetails ? this.Details[0] : null;
      }
    }
    /// <summary>
    /// 获取当前节点的第一个直接后置。
    /// </summary>
    public virtual ConceptPoint FirstRelative
    {
      get
      {
        return this.HasRelatives ? this.Relatives[0] : null;
      }
    }
    /// <summary>
    /// Afterwards 副词，用于打开
    /// FormerParent 属性。
    /// </summary>
    public virtual ConceptPoint Afterwards
    {
      get
      {
        this.AddAttributes(FormerParentLiteral);
        return this;
      }
    }
    /// <summary>
    /// 节点的签名，使用 SignatureKey 属性。
    /// </summary>
    public virtual string Signature
    {
      get
      {
        return this.Attributes.ContainsKey(SignatureKeyLiteral) ? this.Attributes[SignatureKeyLiteral] : null;
      }
      set
      {
        this.Attributes[SignatureKeyLiteral] = value;
      }
    }
    /// <summary>
    /// 判断当前节点是否定义了任何的属性。
    /// </summary>
    public virtual bool HasAttributes
    {
      get
      {
        return this.attributes!=null &&  this.attributes.Count > 0;
      }
    }
    /// <summary>
    /// 判断当前节点是否具有内部细节。
    /// </summary>
    public virtual bool HasDetails
    {
      get
      {
        return this.details!=null && this.details.Count > 0;
      }
    }
    /// <summary>
    /// 判断当前节点是否具有后置节点。
    /// </summary>
    public virtual bool HasRelatives
    {
      get
      {
        return this.relatives!=null && this.relatives.Count > 0;
      }
    }
    /// <summary>
    /// 判断当前节点是否具有前置节点。
    /// </summary>
    public virtual bool HasFormer
    {
      get
      {
        return this.former != null;
      }
    }
    /// <summary>
    /// 判别当前节点是否描过程或者步骤。
    /// </summary>
    public virtual bool IsProcedure
    {
      get
      {
        return this.Header.HasFormer && this.Header.Former.HasRelative(this);
      }
    }
    /// <summary>
    /// 判断当前节点是否描述存在或事物。
    /// </summary>
    public virtual bool IsExistence
    {
      get
      {
        return !this.IsProcedure;
      }
    }
    /// <summary>
    /// 判别当前节点是否具有链接。
    /// </summary>
    /// <remarks>
    /// 具有直接后继或者细节都称为
    /// 具有链接。
    /// </remarks>
    public virtual bool HasLinks
    {
      get
      {
        return this.HasRelatives || this.HasDetails;
      }
    }
    /// <summary>
    /// 获取细节的数量。
    /// </summary>
    public virtual int DetailsCount
    {
      get
      {
        return this.HasDetails ?
          this.Details.Count :
          0;
      }
    }
    /// <summary>
    /// 获取直接后置的数量。
    /// </summary>
    public virtual int RelativesCount
    {
      get
      {
        return this.HasRelatives ?
          this.Relatives.Count :
          0;
      }
    }
    /// <summary>
    /// 获取属性的数量。
    /// </summary>
    public virtual int AttributeCount
    {
      get
      {
        return this.HasAttributes ?
          this.Attributes.Count :
          0;
      }
    }
    /// <summary>
    /// 获取当前节点的所有属性。
    /// </summary>
    public virtual Dictionary<string, string> Attributes
    {
      get
      {
        return this.attributes == null ?
          this.attributes = new Dictionary<string, string>() :
          this.attributes;
      }
    }
    /// <summary>
    /// 获取当前节点的所有内部细节。
    /// </summary>
    public virtual List<ConceptPoint> Details
    {
      get
      {
        return this.details == null ?
          this.details = new List<ConceptPoint>() :
          this.details;
      }
      set
      {
        this.details = value;
      }
    }
    /// <summary>
    /// 获取当前节点的所有直接后继。
    /// </summary>
    public virtual List<ConceptPoint> Relatives
    {
      get
      {
        return this.relatives == null ?
          this.relatives = new List<ConceptPoint>() :
          this.relatives;
      }
      set
      {
        this.relatives = value;
      }
    }
    /// <summary>
    /// 创建带有attributes属性的新节点。
    /// </summary>
    /// <remarks>
    /// 经过此调用，
    /// 新节点的前置将直接设定为当前节点，
    /// 新节点将被返回以便于后置节点的引用。
    /// 新节点将被记录为当前节点的立即后置
    /// 节点。
    /// </remarks>
    public virtual ConceptPoint this[params string[] attributes]
    {
      get
      {
        ConceptPoint nextPoint = of(this,attributes);
        if (nextPoint != null && this.AutoRelative)
        {
          this.AddRelatives(nextPoint);
        }
        return nextPoint;
      }
    }
    /// <summary>
    /// 创建带有points内容的新节点。
    /// </summary>
    /// <remarks>
    /// 经过此调用，
    /// 新节点的前置将直接设定为当前节点，
    /// 新节点将被返回以便于后置节点的引用。
    /// 新节点将被记录为当前节点的立即后置
    /// 节点。
    /// </remarks>
    public virtual ConceptPoint this[params ConceptPoint[] points]
    {
      get
      {
        ConceptPoint nextPoint = of(this, points);
        if (nextPoint != null && this.AutoRelative)
        {
          this.AddRelatives(nextPoint);
        }
        return nextPoint;
      }
    }
    /// <summary>
    /// 判别是否直接将方括号语法中生成的新节点加入到
    /// 当前节点的后继之中，缺省为true。
    /// </summary>
    protected virtual bool AutoRelative
    {
      get
      {
        return true;
      }
    }
    #endregion
    #region Constructors
    public ConceptPoint()
    {

    }
    public ConceptPoint(ConceptPoint former)
    {
      this.former = former;
    }
    public ConceptPoint(params string[] attributes)
      : this(null, attributes)
    {
    }
    public ConceptPoint(params ConceptPoint[] details)
      : this(null, details)
    {
    }
    public ConceptPoint(ConceptPoint former, params string[] attributes):this(former)
    {
      this.AddAttributes(attributes);
    }
    public ConceptPoint(ConceptPoint former, params ConceptPoint[] details)
      : this(former)
    {
      this.AddDetails(details);
    }
    #endregion
    #region Methods
    #region Publics
    public virtual bool HasAttribute(string attribute)
    {
      return attribute!=null && this.Attributes.ContainsKey(attribute);
    }
    public virtual bool HasRelative(ConceptPoint point)
    {
      return point != null ? this.Relatives.Contains(point) : false;
    }
    public virtual ConceptPoint AddAttribute(string attribute, string value)
    {
      if (attribute != null)
      {
        this.Attributes.Add(attribute, value);
      }
      return this;
    }
    public virtual ConceptPoint AddAttributes(params string[] attributes)
    {
      if (attributes != null)
      {
        foreach (string attribute in attributes)
        {
          if (!this.Attributes.ContainsKey(attribute))
          {
            this.Attributes.Add(attribute, null);
          }
        }
      }
      return this;
    }
    public virtual ConceptPoint RemoveAttributes(params string[] attributes)
    {
      if (attributes != null)
      {
        foreach (string attribute in attributes)
        {
          if (attribute != null)
          {
            this.Attributes.Remove(attribute);
          }
        }
      }
      return this;
    }
    public virtual ConceptPoint AddRelatives(params ConceptPoint[] points)
    {
      if (points != null)
      {
        foreach (ConceptPoint node in points)
        {
          this.Relatives.Add(node);
        }
      }
      return this;
    }
    public virtual ConceptPoint RemoveRelatives(params ConceptPoint[] points)
    {
      if (points != null)
      {
        foreach (ConceptPoint node in points)
        {
          this.Relatives.Remove(node);
        }
      }
      return this;
    }
    public virtual ConceptPoint AddDetails(params ConceptPoint[] points)
    {
      if (points != null)
      {
        this.Details.AddRange(this.OnAddDetails(points));
      }
      return this;
    }
    public virtual ConceptPoint RemoveDetials(params ConceptPoint[] points)
    {
      if (points != null)
      {
        foreach (ConceptPoint node in this.OnRemoveDetails(points))
        {
          this.Details.Remove(node);
        }
      }
      return this;
    }
    #endregion
    #region Grammar Helpers
    public virtual ConceptPoint with(params string[] attributes)
    {
      return this.AddAttributes(attributes);
    }
    public virtual ConceptPoint with(params ConceptPoint[] points)
    {
      return this.AddDetails(points);
    }
    #endregion
    #region Internals
    protected virtual ConceptPoint[] OnAddDetails(ConceptPoint[] points)
    {
      if (points != null)
      {
        foreach (ConceptPoint point in points)
        {
          if (point != null && point.HasAttribute(FormerParentLiteral))
          {
            point.Former = this;
            this.AddRelatives(point);
          }
        }
      }
      return points;
    }
    protected virtual ConceptPoint[] OnRemoveDetails(ConceptPoint[] points)
    {
      if (points != null)
      {
        foreach (ConceptPoint point in points)
        {
          if (point != null && point.HasAttribute(FormerParentLiteral))
          {
            point.Former = null;
            this.RemoveRelatives(point);
          }
        }
      }
      return points;
    }
    #endregion
    #endregion
  }


  public class ConceptNetwork
  {
    #region Fields
    protected ICollection<ConceptPoint> points = new LinkedList<ConceptPoint>();
    #endregion
    #region Properties
    public virtual ICollection<ConceptPoint> Points
    {
      get
      {
        return this.points;
      }
    }
    #endregion
    #region Methods
    protected virtual ConceptPoint FindPoint(string signature)
    {
      return null;
    }

    protected virtual ConceptPoint Inspect(ConceptPoint point)
    {
      return point!=null ? this.Inspect(point, null) : null;
    }
    /// <summary>
    /// 尝试理解概念点所表达的内容。
    /// </summary>
    protected virtual ConceptPoint Inspect(ConceptPoint point,List<ConceptPoint> peers)
    {
      if (point != null)
      {
        //递归检索内置
        if (point.HasDetails)
        {
          List<ConceptPoint> modifieds = new List<ConceptPoint>();
          //检索全部内置
          //为了保证内置的无序性，必须同时传入内置的同层点。
          //这种前置的内置递归要求必须将概念点分析到底，
          //然后才逐渐的向上进行类型判别。
          foreach (ConceptPoint detail in point.Details)
          {
            modifieds.Add(this.Inspect(detail, point.Details));
          }
          //提交内部节点的改动。
          this.CommitDetails(point, modifieds);
        }
        else //至此，节点没有任何内置点，但可能还具有并置点（peers）和后置点（Relatives）。
        {
          if (peers != null)
          {
            point = this.InspectTrailing(point, peers);
          }
          else //仅在顶层节点传入时发生。
          {

          }
        }
      }

      return point;
    }
    /// <summary>
    /// 尝试理解后置（排列）
    /// </summary>
    protected virtual ConceptPoint InspectTrailing(ConceptPoint point, List<ConceptPoint> peers)
    {
      //检索并置
      if (point.HasRelatives)
      {
        LinkedList<ConceptPoint> unknownPoints = new LinkedList<ConceptPoint>();
        //替换所有已知节点
        //记录所有未知节点
        foreach (ConceptPoint relative in point.Relatives)
        {
          if (relative != null)
          {
            ConceptPoint cp = null;
            if (!this.LinkKnownPoint(ref cp))
            {
              unknownPoints.AddLast(relative);
            }
          }
        }
        //若存在未知节点
        if (unknownPoints.Count > 0)
        {
          //若未知节点只有一个，则可能是“并置”。
          //若未知节点数目很多，则可能是“排列”。
        }
      }
      return point;
    }

    protected virtual ConceptPoint CommitDetails(ConceptPoint point, List<ConceptPoint> details)
    {
      if (point != null && details != null)
      {
        point.Details = details;
      }
      return point;
    }
    protected virtual bool LinkKnownPoint(ref ConceptPoint point)
    {
      return true;
    }



    protected enum AttributeDirection
    {
      Sequantial = 0,
      Recursive  = 1,
    }


    /// <summary>
    /// 判别候选节点是否为可能的模式节点。
    /// </summary>
    protected virtual bool IsPattern(ConceptPoint candidate)
    {
      if (candidate != null && candidate.RelativesCount == 1)
      {
        ConceptPoint relative = candidate.FirstRelative;

        if (relative != null && !relative.HasRelatives)
        {
          return true;
        }
      }
      return false;
    }
    /// <summary>
    /// 学习二元关系给出的模式。
    /// </summary>
    /// <remarks>
    /// 只有使用严格的二元关系的时候才可以
    /// 进行模式学习。
    /// </remarks>
    protected virtual void LearnPattern(ConceptPoint candidate)
    {
      if (this.IsPattern(candidate))
      {
        this.LearnPattern(candidate, candidate.FirstRelative);
      }
    }
    /// <summary>
    /// 学习二元关系给出的模式。
    /// </summary>
    protected virtual void LearnPattern(ConceptPoint pattern,ConceptPoint relative)
    {
      ConceptPoint def = null;

      if (pattern != null && relative != null && pattern.HasDetails && relative.HasDetails)
      {
        int PatternDetailsCount = pattern.DetailsCount;

        int RelativeDetailsCount = relative.DetailsCount;

        if (PatternDetailsCount == 1)
        {
          //获取唯一的内部节点。
          if ((def = pattern.FirstDetail) != null)
          {
            //如果出现对Any的引用，则转入学习属性的用法。
            //此时Left和Right不对称！
            if (def.HasAttribute(ConceptPoint.AnyLiteral))
            {
              this.LearnAttributes(def, relative);
            }
          }
        }
        else if (RelativeDetailsCount == 1)
        {
          //获取唯一的内部节点。
          if ((def = relative.FirstDetail) != null)
          {
            //如果出现对Any的引用，则转入学习属性的用法。
            //此时Left和Right不对称！
            if (def.HasAttribute(ConceptPoint.AnyLiteral))
            {
              this.LearnAttributes(def, pattern);
            }
          }
        }
        else //都具有两个以上节点（应该是两个）
        {

        }
      }
    }
    /// <summary>
    /// 学习属性的用法。
    /// </summary>
    protected virtual void LearnAttributes(ConceptPoint def,ConceptPoint descriptions)
    {
      ///def 没有内部节点。
      if (def != null && descriptions != null)
      {
        if (!def.HasLinks && descriptions.HasDetails)
        {
        }
      }
    }
    #endregion
  }
}
